package com.luxiu.extensionlib.button

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.StateListDrawable
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatButton
import androidx.core.content.ContextCompat
import com.luxiu.extensionlib.R

/**
 *  <VariousButton
 *      android:id="@+id/text_test"
 *      android:layout_width="100dp"
 *      android:layout_height="60dp"
 *      android:layout_gravity="center_horizontal"
 *      android:layout_margin="10dp"
 *      android:padding="10dp"
 *      app:mStrokeDashGap="@dimen/dp_5"
 *      app:mStrokeDashLong="@dimen/dp_5"
 *      app:mStrokeWidth="@dimen/dp_5"
 *      app:mButtonRadius="@dimen/dp_50"
 *      app:mNormalBackgroundColor="@color/colorPrimary"
 *      app:mNormalTextColor="@android:color/white"
 *      app:mPressedBackgroundColor="@color/black"
 *      app:mPressedTextColor="@android:color/white"
 *      app:mUnableBackgroundColor="@color/colorPrimary"
 *      app:mUnableTextColor="@android:color/holo_orange_dark"
 *      app:mNormalStrokeColor="@android:color/white"
 *      app:mPressedStrokeColor="@android:color/holo_red_light"
 *      app:mUnableStrokeColor="@android:color/holo_orange_dark"
 *  />
 */
class VariousButton(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    AppCompatButton(context, attrs, defStyleAttr) {
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    /**
     * 常态字体颜色
     */
    private var mNormalTextColor = 0

    /**
     * 点击字体颜色
     */
    private var mPressedTextColor = 0

    /**
     * 不可用字体颜色
     */
    private var mUnableTextColor = 0

    /**
     * 边框线长度
     */
    private var mStrokeDashLong = 0f

    /**
     * 边框线宽度
     */
    private var mStrokeDashGap = 0f

    /**
     * 边框线
     */
    private var mStrokeWidth = 0

    /**
     * 常态边框颜色
     */
    private var mNormalStrokeColor = 0

    /**
     * 点击边框颜色
     */
    private var mPressedStrokeColor = 0

    /**
     * 不可用边框颜色
     */
    private var mUnableStrokeColor = 0

    /**
     * 常态背景色
     */
    private var mNormalBackground: GradientDrawable = GradientDrawable()

    /**
     * 点击时背景色
     */
    private var mPressedBackground: GradientDrawable = GradientDrawable()

    /**
     * 不可用时背景色
     */
    private var mUnableBackground: GradientDrawable = GradientDrawable()

    private var states: Array<IntArray?> = arrayOfNulls(4)

    private var mStateBackground: StateListDrawable = background as? StateListDrawable ?: StateListDrawable()

    init {

        states[0] = intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed)
        states[1] = intArrayOf(android.R.attr.state_enabled, android.R.attr.state_focused)
        states[3] = intArrayOf(-android.R.attr.state_enabled)
        states[2] = intArrayOf(android.R.attr.state_enabled)

        val a = context.obtainStyledAttributes(attrs, R.styleable.VariousButton)


        try {
            mNormalTextColor =
                a.getColor(R.styleable.VariousButton_mNormalTextColor, textColors.getColorForState(states[2], currentTextColor))
            mPressedTextColor =
                a.getColor(R.styleable.VariousButton_mPressedTextColor, textColors.getColorForState(states[0], currentTextColor))
            mUnableTextColor =
                a.getColor(R.styleable.VariousButton_mUnableTextColor, textColors.getColorForState(states[3], currentTextColor))
            setTextColor()

            val duration = a.getInteger(R.styleable.VariousButton_mAnimationDuration, 0)
            mStateBackground.setEnterFadeDuration(duration)
            mStateBackground.setExitFadeDuration(duration)

            mNormalBackground.setColor(a.getColor(R.styleable.VariousButton_mNormalBackgroundColor, 0))
            mPressedBackground.setColor(a.getColor(R.styleable.VariousButton_mPressedBackgroundColor, 0))
            mUnableBackground.setColor(a.getColor(R.styleable.VariousButton_mUnableBackgroundColor, 0))

            val radius = a.getDimensionPixelSize(R.styleable.VariousButton_mButtonRadius, 0).toFloat()
            mNormalBackground.cornerRadius = radius
            mPressedBackground.cornerRadius = radius
            mUnableBackground.cornerRadius = radius

            mStrokeDashLong = a.getDimensionPixelSize(R.styleable.VariousButton_mStrokeDashLong, 0).toFloat()
            mStrokeDashGap = a.getDimensionPixelSize(R.styleable.VariousButton_mStrokeDashGap, 0).toFloat()
            mStrokeWidth = a.getDimensionPixelSize(R.styleable.VariousButton_mStrokeWidth, 0)
            mNormalStrokeColor = a.getColor(R.styleable.VariousButton_mNormalStrokeColor, 0)
            mPressedStrokeColor = a.getColor(R.styleable.VariousButton_mPressedStrokeColor, 0)
            mUnableStrokeColor = a.getColor(R.styleable.VariousButton_mUnableStrokeColor, 0)
            setStroke()
        } finally {
            a.recycle()
        }
        mStateBackground.addState(states[0], mPressedBackground)
        mStateBackground.addState(states[1], mPressedBackground)
        mStateBackground.addState(states[3], mUnableBackground)
        mStateBackground.addState(states[2], mNormalBackground)
        setBackgroundDrawable(mStateBackground)
    }


    fun setNormalStrokeColor(normalStrokeColor: Int) {
        mNormalStrokeColor = normalStrokeColor
        setStroke(mNormalBackground, normalStrokeColor, mStrokeWidth)
    }

    fun setPressedStrokeColor(pressedStrokeColor: Int) {
        mPressedStrokeColor = pressedStrokeColor
        setStroke(mPressedBackground, pressedStrokeColor, mStrokeWidth)
    }

    fun setUnableStrokeColor(unableStrokeColor: Int) {
        mUnableStrokeColor = unableStrokeColor
        setStroke(mUnableBackground, unableStrokeColor, mStrokeWidth)
    }

    fun setStateStrokeColor(normal: Int, pressed: Int, unable: Int) {
        mNormalStrokeColor = normal
        mPressedStrokeColor = pressed
        mUnableStrokeColor = unable
        setStroke()
    }

    fun setStrokeWidth(normalStrokeWidth: Int) {
        mStrokeWidth = normalStrokeWidth
        setStroke(mNormalBackground, mNormalStrokeColor, mStrokeWidth)
    }

    fun setStrokeDash(strokeDashLong: Float, strokeDashGap: Float) {
        mStrokeDashLong = strokeDashLong
        mStrokeDashGap = strokeDashGap
        setStroke()
    }

    private fun setStroke() {
        setStroke(mNormalBackground, mNormalStrokeColor, mStrokeWidth)
        setStroke(mPressedBackground, mPressedStrokeColor, mStrokeWidth)
        setStroke(mUnableBackground, mUnableStrokeColor, mStrokeWidth)
    }

    private fun setStroke(mBackground: GradientDrawable, mStrokeColor: Int, mStrokeWidth: Int) {
        mBackground.setStroke(
            mStrokeWidth,
            if (mStrokeColor == 0) 0 else ContextCompat.getColor(context, mStrokeColor),
            mStrokeDashLong,
            mStrokeDashGap
        )
    }

    fun setStateBackgroundColor(normal: Int, pressed: Int, unable: Int) {
        mNormalBackground.setColor(ContextCompat.getColor(context, normal))
        mPressedBackground.setColor(ContextCompat.getColor(context, pressed))
        mUnableBackground.setColor(ContextCompat.getColor(context, unable))
        mStateBackground.addState(states[2], mNormalBackground)
        mStateBackground.addState(states[0], mPressedBackground)
        mStateBackground.addState(states[3], mUnableBackground)
        setBackgroundDrawable(mStateBackground)
    }

    fun setNormalBackgroundColor(normalBackgroundColor: Int) {
        mNormalBackground.setColor(ContextCompat.getColor(context, normalBackgroundColor))
        mStateBackground.addState(states[2], mNormalBackground)
        setBackgroundDrawable(mStateBackground)
    }

    fun setPressedBackgroundColor(pressedBackgroundColor: Int) {
        mPressedBackground.setColor(ContextCompat.getColor(context, pressedBackgroundColor))
        mStateBackground.addState(states[0], mPressedBackground)
        setBackgroundDrawable(mStateBackground)
    }

    fun setUnableBackgroundColor(unableBackgroundColor: Int) {
        mUnableBackground.setColor(ContextCompat.getColor(context, unableBackgroundColor))
        mStateBackground.addState(states[3], mUnableBackground)
        setBackgroundDrawable(mStateBackground)
    }

    fun setAnimationDuration(duration: Int) {
        mStateBackground.setEnterFadeDuration(duration)
    }

    private fun setTextColor() {
        val colors = intArrayOf(mPressedTextColor, mPressedTextColor, mNormalTextColor, mUnableTextColor)
        setTextColor(ColorStateList(states, colors))
    }

    fun setStateTextColor(normal: Int, pressed: Int, unable: Int) {
        mNormalTextColor = normal
        mPressedTextColor = pressed
        mUnableTextColor = unable
        setTextColor()
    }

    fun setNormalTextColor(normalTextColor: Int) {
        mNormalTextColor = normalTextColor
        setTextColor()
    }

    fun setPressedTextColor(pressedTextColor: Int) {
        mPressedTextColor = pressedTextColor
        setTextColor()
    }

    fun setUnableTextColor(unableTextColor: Int) {
        mUnableTextColor = unableTextColor
        setTextColor()
    }

    fun setRadius(radius: Float) {
        mNormalBackground.cornerRadius = radius
        mPressedBackground.cornerRadius = radius
        mUnableBackground.cornerRadius = radius
    }

    fun setRadius(radius: FloatArray?) {
        mNormalBackground.cornerRadii = radius
        mPressedBackground.cornerRadii = radius
        mUnableBackground.cornerRadii = radius
    }
}